import { AxiosRequestConfig, AxiosRequestHeaders } from 'axios';
import request, { ADAPTER_TYPE, AxiosRequestConfigMergeDataNotFormData } from './axios/index';

type HeadersType = {
  /**
   * 小程序请求底层切换request/upload,
   */
  $requestType: ADAPTER_TYPE.REQUEST | ADAPTER_TYPE.UPLOAD;
};
interface AxiosRequestConfigMerge extends AxiosRequestConfig {
  headers: AxiosRequestHeaders & HeadersType;
}

interface RequestConfigOptionsBase {
  /**
   * 开发者服务器 url
   */
  url: string;
  /**
   * HTTP 请求 Header, header 中不能设置 Referer
   */
  headers?: AxiosRequestHeaders;
  /**
   * url传参, {name: 'XXX'}输入内容到时候可以放在url?name=XXX
   */
  params?: Record<string, any>;
}

export interface RequestConfigOptions extends RequestConfigOptionsBase {
  /**
   * body传输的data 或 upload传输方式的formdata
   */
  data?: Record<string, any>;
}

export type RequestConfigOptionsForUpload = RequestConfigOptions & AxiosRequestConfigMergeDataNotFormData;

export enum MethodEnum {
  GET = 'GET',
  POST = 'POST',
  PUT = 'PUT',
  DELETE = 'DELETE'
}

/**
 * http的get请求
 * @param config 请求内容配置
 * @returns promise
 */
export function GET(config: RequestConfigOptionsBase) {
  return request({
    ...config,
    method: MethodEnum.GET
  });
}

/**
 * http的post请求
 * @param config 请求内容配置
 * @returns promise
 */
export function POST(config: RequestConfigOptions) {
  return request({
    ...config,
    method: MethodEnum.POST
  });
}

/**
 * http的put请求
 * @param config 请求内容配置
 * @returns promise
 */
export function PUT(config: RequestConfigOptions) {
  return request({
    ...config,
    method: MethodEnum.PUT
  });
}

/**
 * http的delete请求
 * @param config 请求内容配置
 * @returns promise
 */
export function DELETE(config: RequestConfigOptions) {
  return request({
    ...config,
    method: MethodEnum.DELETE
  });
}

/**
 * 文件上传的方法
 * @param config 文件上传方法的配置
 * @returns 返回promise
 */
export function UPLOAD(config: RequestConfigOptionsForUpload) {
  const requestOptions: AxiosRequestConfigMerge = {
    ...config,
    headers: {
      $requestType: ADAPTER_TYPE.UPLOAD,
      ...config.headers
    },
    data: {
      fileType: config.fileType,
      file: config.file,
      filePath: config.filePath,
      name: config.name,
      files: config.files,
      formData: config.data
    }
  };
  return request(requestOptions);
}
